// ExcuteAppManager.cpp: implementation of the ExcuteAppManager class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "GameStart.h"
#include "ExcuteAppManager.h"
#include "../Release/GameCoreApi.h"

#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
 

static unsigned char load_code[] = {0x6A, 0x00, 0x60, 0x9C, 0xE8, 0x00, 0x00, 0x00, 0x00, 0x5E, 0x81, 0xE6, 0x00, 0x00, 0xFF, 0xFF, 0xAD, 0x89, 0x44, 0x24, 0x24, 0xAD, 0x56, 0xFF, 0xD0, 0x9D, 0x61, 0xC3};

void Inject(TCHAR *ExeFile, TCHAR *LibFile, TCHAR *lpCmdLine)
{
	STARTUPINFO info;
	PROCESS_INFORMATION pi;
	CONTEXT ctx;
	MEMORY_BASIC_INFORMATION mbi;
	DWORD loadfun, p;
	TCHAR WORK_DIR[256];
	int len;
	
	memset(&info, 0, sizeof(info));
	memset(&pi, 0, sizeof(pi));
	memset(&ctx, 0, sizeof(ctx));
	memset(&mbi, 0, sizeof(mbi));
	
	_tcscpy(WORK_DIR, ExeFile);
	*_tcschr(WORK_DIR, '\\') = 0;
	if (!CreateProcess(ExeFile, lpCmdLine, NULL, NULL, FALSE, CREATE_SUSPENDED, NULL, WORK_DIR, &info, &pi)) return ;
	ctx.ContextFlags = CONTEXT_FULL;
	GetThreadContext(pi.hThread, &ctx);
	
	len = _tcslen(LibFile) + sizeof(TCHAR);
	loadfun = (DWORD)GetProcAddress(GetModuleHandle(_T("kernel32.dll")), "LoadLibraryW");
	BYTE *lpbuf = (BYTE *)VirtualAllocEx(pi.hProcess, NULL, 0x1000, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
	
	WriteProcessMemory(pi.hProcess, lpbuf, &ctx.Eax, 4, &p);
	WriteProcessMemory(pi.hProcess, lpbuf + 4, &loadfun, 4, &p);
	WriteProcessMemory(pi.hProcess, lpbuf + 8, LibFile, len, &p);
	WriteProcessMemory(pi.hProcess, lpbuf + 8 + len, &load_code, sizeof(load_code), &p);
	
	ctx.Eax = (DWORD)lpbuf + 8 + len;
	SetThreadContext(pi.hThread, &ctx);
	
	ResumeThread(pi.hThread);
	
	//VirtualFreeEx(pi.hProcess, lpbuf, 0x1000, MEM_RELEASE);
	
	CloseHandle(pi.hThread);
	CloseHandle(pi.hProcess);
}


int CExcuteAppManager::CreateExcuteApp(CString strApp,CString strCmdLine,PROCESS_INFORMATION& processInfo)
{
	//PROCESS_INFORMATION processInfo;
	STARTUPINFO startInfo;
	TCHAR *pCmdLine=NULL;
	if(!strCmdLine.IsEmpty())
	{
		int nLength=strCmdLine.GetLength();
		pCmdLine=new TCHAR[strCmdLine.GetLength()+1];
		memset(pCmdLine,0,nLength+1);
		lstrcpy(pCmdLine,strCmdLine); 
	}
// 	ZeroMemory(&startInfo,sizeof(startInfo));
// 	startInfo.cb=sizeof(startInfo); 
// 	PROCESS_INFORMATION pi;
// 	CreateProcess(strApp,pCmdLine,NULL,NULL,FALSE,CREATE_SUSPENDED,NULL,NULL,&startInfo,&processInfo);
	Inject(_T("H:\\blade\\bin\\Client.exe"), _T("H:\\blade\\bin\\Inject.dll"), _T("/LaunchByLauncher"));
// 	
// 	CString cs;
// 	cs.Format(_T("%d , %d"), processInfo.hProcess, processInfo.dwProcessId);
// 	AfxMessageBox(cs);
// 	
// 	typedef int (__stdcall *pLoadLibraryW)();
// 	pLoadLibraryW pOldAddr = (pLoadLibraryW)GetProcAddress(GetModuleHandle(_T("kernel32.dll")),"LoadLibraryW");
// 	
// 
// 	PDWORD m_pDataRemote = (PDWORD)::VirtualAllocEx(processInfo.hProcess,0,100,MEM_COMMIT,PAGE_READWRITE); 
// 	WriteProcessMemory(processInfo.hProcess, m_pDataRemote,_T("H:\\blade\\bin\\Inject.dll"), 90, NULL);
// 	CreateRemoteThread(processInfo.hProcess,NULL,0,(LPTHREAD_START_ROUTINE)pOldAddr,(LPVOID)m_pDataRemote,0,NULL);
// 	ResumeThread(processInfo.hThread);
		SAFE_DELETE_STRUCT(pCmdLine);
		return 1;

	SAFE_DELETE_STRUCT(pCmdLine);	
	return 0;
}

BOOL CExcuteAppManager::StartApp()
{
	m_func.GetAppFilePathList();
	CString strTemp=_T("");
	for(int i=0;i<m_func.m_arrDictionList.GetSize();i++)
	{
		lpAPP_ENTITY processInfo =new APP_ENTITY();
		strTemp=m_func.m_arrDictionList.GetAt(i);
		processInfo->statu=Init;
		processInfo->strAppFilePath=strTemp;
		if(CreateExcuteApp(strTemp,_T("/LaunchByLauncher"),processInfo->ProcessInfo)>0)
		{
// 			m_AppProcessList.Add(processInfo);
// 			while(!SetHook(processInfo->ProcessInfo))
// 			{
// 				Sleep(2000);
// 			}
		}
	}
	return TRUE;
}
 